/** 主要作用是连接 maincontent 和 formrender之间的联系
 * 提供util方法，比如：
 * 1、生成id
 * 2、接收画布config和组件new config 从而更新画布config中内容
 */
import {
  IWidgetJson,
  IColumn,
} from '@/components/common/VisualizationDashboard/interface'
import ThemeColorPicker from '@/components/common/VisualizationDashboard/CustomizeComponent/ThemeColorPicker.vue'
import GeoMapThemeSelect from '@/components/common/VisualizationDashboard/CustomizeComponent/GeoMapThemeSelect.vue'
import InputNumberRange from '@/components/common/VisualizationDashboard/CustomizeComponent/InputNumberRange.vue'
import IconRadio from '@/components/form/IconRadio.vue'
import ColorPicker from '@/components/form/color-picker.vue'
import { getWidgetData, loadGraphData } from '@/api/widget'
import { cloneDeep } from 'lodash'
import { dealMapData } from '@/components/studio/data/util'
import FilterColumnSelector from '@/components/common/VisualizationDashboard/FilterColumnSelector.vue'
import AssociatedChartSelection from '@/components/common/VisualizationDashboard/associated-chart-selection.vue'
import { GridItemDataInterface } from '@/components/interface/grid-item-data-interface'
import SimpleColumnSelect from '@/components/common/VisualizationDashboard/CustomizeComponent/SimpleColumnSelect.vue'
import SimpleUpload from '@/components/common/VisualizationDashboard/CustomizeComponent/SimpleUpload.vue'
import GroupSelect from '@/components/form/group-select.vue'
import Big from 'big.js'

export const widgetTypeEnum = {
  system: 'system',
  pipeline: 'pipeline',
  dataset: 'dataset',
}

export interface IKeyValue {
  [key: string]: any
}

export const dynamicComponent = {
  ThemeColorPicker,
  ColorPicker,
  IconRadio,
  GeoMapThemeSelect,
  FilterColumnSelector,
  AssociatedChartSelection,
  InputNumberRange,
  GroupSelect,
  SimpleColumnSelect,
  SimpleUpload,
}

export const dynamicCompMaps: IKeyValue = {
  colorPicker: {
    component: 'color-picker',
    props: {},
  },
  geoMapThemeSelect: {
    component: 'geo-map-theme-select',
    props: {},
  },
  multipleSelect: {
    component: 'multiple-select',
    props: {},
  },
  inputNumber: {
    component: 'a-input-number',
    props: {},
  },
  inputNumberRange: {
    component: 'input-number-range',
    props: {},
  },
  text: {
    component: 'a-input',
    props: {},
  },
  radioGroup: {
    component: 'a-radio-group',
    props: {},
  },
  checkboxGroup: {
    component: 'a-checkbox-group',
    props: {},
  },
  select: {
    component: 'a-select',
    props: {},
  },
  switch: {
    component: 'a-switch',
    props: {},
  },
  themeColorRadio: {
    component: 'theme-color-radio',
    props: {},
  },
  paddingSetter: {
    component: 'padding-setter',
    props: {},
  },
  rangePicker: {
    component: 'a-range-picker',
    props: {},
  },
  rangeYear: {
    component: 'rangeYear',
    props: {},
  },
  rangeMonth: {
    component: 'rangeMonth',
    props: {},
  },
  rangeDay: {
    component: 'rangeDay',
    props: {},
  },
  columnSelector: {
    component: 'columnSelector',
    props: {},
  },
  iconRadio: {
    component: 'icon-radio',
    props: {},
  },
  demoTemplate: {
    component: 'customize-form-item-template',
  },
  themeColorPicker: {
    component: 'theme-color-picker',
  },
  slider: {
    component: 'a-slider',
  },
  fleterColumnSelector: {
    component: 'filter-column-selector',
  },
  checkbox: {
    component: 'a-checkbox-group',
  },
  AssociatedChartSelection: {
    component: 'associated-chart-selection',
  },
  GroupSelect: {
    component: 'group-select',
  },
  simpleColumnSelect: {
    component: 'simple-column-select',
  },
  upload: {
    component: 'simple-upload',
  },
}

// 禁止tooltip formatter 转换的chart，原因：这些图需要展示多项，目前的formatter 不支持多项
const disableTooltipFormatterChart = new Set([
  'scatterplot',
  'bubbleScatterChart',
  'wordCloud',
])

// function parseTitleSetting(setting: IKeyValue) {
//   if (setting.title) {
//     setting.titleIsShow = true
//   }
// }

/**
 * 解析chartType
 * @param chartType 'barChart' | ['barChart', 'barChart']
 * @returns 'barChart'
 */
export function parseChartType(chartType: string | string[]): string {
  if (Array.isArray(chartType)) {
    return chartType[1] || chartType[0]
  }
  return chartType
}

/**
 * 配置的解析函数，将1对多或者多对1的情况进行解析
 * settingToChartOption：把form的配置转换成chart接受的 chartOption
 * chartOptionToSetting：把chartOption 转换成 form 的表单值
 */
const parseSettingFunction: IKeyValue = {
  titleSetting: {
    // 图表标题
    settingToChartOption: (setting: IKeyValue) => {
      if (setting.title) {
        setting.titleIsShow = true
      } else {
        setting.titleIsShow = false
      }
      return setting
    },
  },
  legendSetting: {
    // 图例
    settingToChartOption: (setting: IKeyValue) => {
      if (setting.legendPosition === 'null') {
        // 不开启图例
        setting.legendIsShow = false
        setting.legendPosition = 'null'
      } else {
        setting.legendIsShow = true
      }
      return setting
    },
  },
  layoutSetting: {
    // 布局：垂直布局、水平布局
    settingToChartOption: (setting: IKeyValue) => {
      // console.log('parseLayoutSetting =======>', setting)
      return setting
    },
  },
  gridSetting: {
    // 网格线
    settingToChartOption: (setting: IKeyValue) => {
      ;['xAxisGridStyle', 'yAxisGridStyle'].forEach((key: string) => {
        const target =
          key === 'xAxisGridStyle' ? 'xAxisGridIsShow' : 'yAxisGridIsShow'
        if (setting[key] !== 'null') {
          // 网格线选的不是无，IsShow要设为true
          setting[target] = true
        } else {
          // 网格线选的是无，IsShow设为false，隐藏网格线
          setting[target] = false
          setting[key] = 'null'
        }
      })
      return setting
    },
    chartOptionToSetting: (chartOptions: IKeyValue) => {
      ;['xAxisGridIsShow', 'yAxisGridIsShow'].forEach((key: string) => {
        const target =
          key === 'xAxisGridIsShow' ? 'xAxisGridStyle' : 'yAxisGridStyle'
        if (chartOptions[key] === false) {
          // IsShow设为false 即 form里 网格线的选项选的是 ’无‘
          chartOptions[target] = 'null'
        }
      })
      return chartOptions
    },
  },
  yAxisSetting: {
    settingToChartOption: (setting: IKeyValue) => {
      ;['yAxisMin', 'yAxisMax'].forEach((key: string) => {
        const target = key === 'yAxisMin' ? 'min' : 'max'
        if (
          setting[key] !== '' &&
          setting[key] !== null &&
          setting[key] !== undefined
        ) {
          if (setting.yAxis === null || setting.yAxis === undefined) {
            setting.yAxis = {}
          }
          setting.yAxis[target] = Number(setting[key])
        } else {
          if (setting.yAxis === null || setting.yAxis === undefined) {
            setting.yAxis = {}
          }
          setting.yAxis[target] = undefined
        }
      })
      return setting
    },
    chartOptionToSetting: (chartOptions: IKeyValue) => {
      ;['min', 'max'].forEach((key: string) => {
        const target = key === 'min' ? 'yAxisMin' : 'yAxisMax'
        if (chartOptions?.yAxis[key] !== undefined) {
          chartOptions[target] = chartOptions?.yAxis[key]
        } else {
          chartOptions[target] = ''
        }
      })
      return chartOptions
    },
  },
  xAxisSetting: {
    settingToChartOption: (setting: IKeyValue) => {
      ;['xAxisMin', 'xAxisMax'].forEach((key: string) => {
        const target = key === 'xAxisMin' ? 'min' : 'max'
        if (
          setting[key] !== '' &&
          setting[key] !== null &&
          setting[key] !== undefined
        ) {
          if (setting.xAxis === null || setting.xAxis === undefined) {
            setting.xAxis = {}
          }
          setting.xAxis[target] = Number(setting[key])
        } else {
          if (setting.xAxis === null || setting.xAxis === undefined) {
            setting.xAxis = {}
          }
          setting.xAxis[target] = undefined
        }
      })
      return setting
    },
    chartOptionToSetting: (chartOptions: IKeyValue) => {
      ;['min', 'max'].forEach((key: string) => {
        const target = key === 'min' ? 'xAxisMin' : 'xAxisMax'
        if (chartOptions?.xAxis[key] !== undefined) {
          chartOptions[target] = chartOptions?.xAxis[key]
        } else {
          chartOptions[target] = ''
        }
      })
      return chartOptions
    },
  },
  labelSetting: {
    settingToChartOption: (setting: IKeyValue) => {
      if (setting.labelIsShow) {
        if (setting.label === null || setting.label === undefined) {
          setting.label = {}
        }
        if (setting.labelPosition !== undefined) {
          // 柱状图
          setting.label.position = setting.labelPosition
        }
        if (setting.labelType !== undefined) {
          // 柱状图
          setting.label.type = setting.labelType
        }

        // AreaRangeChart和BoxLineChart需要特殊处理
        const rangeFlag =
          setting.realChartType === 'AreaRangeChart' ||
          setting.realChartType === 'BoxLineChart'

        // 百分比和精度设置
        const { labelIsPercent, labelPrecision, valueKey, yAxisAttribute } =
          setting
        const precisionFlag =
          typeof labelPrecision === 'number' &&
          labelPrecision >= 0 &&
          labelPrecision <= 9 // 小数位数 0-9之间
        setting.label.formatter = (data: any) => {
          // 是否进入formatter处理
          const isMultiYAxisAttribute =
            rangeFlag ||
            (Array.isArray(yAxisAttribute) && yAxisAttribute.length > 1)
          let values = isMultiYAxisAttribute ? data.value : data[valueKey]
          const isArrayValue = Array.isArray(values) // 是否为数组格式
          if (!isArrayValue) {
            values = [values] // 全部构造成数组格式
          }
          if (!values.some((v: any) => typeof v !== 'number')) {
            values = values.map((v: any) => {
              let value: any = new Big(v)
              if (labelIsPercent) {
                value = value.times(100)
              }
              if (precisionFlag) {
                value = value.toFixed(labelPrecision)
              } else {
                value = value.toNumber()
              }
              return labelIsPercent ? `${value}%` : value
            })
          }
          return isArrayValue ? values : values[0]
        }
      } else {
        setting.label = {}
      }
      return setting
    },
    chartOptionToSetting: (chartOptions: IKeyValue) => {
      if (chartOptions.labelIsShow === undefined) {
        chartOptions.labelIsShow =
          chartOptions.label !== undefined && chartOptions.label !== {}
      }

      chartOptions.labelPosition = chartOptions.label.position
        ? chartOptions.label.position
        : chartOptions.labelPosition
        ? chartOptions.labelPosition
        : 'middle'
      chartOptions.labelType = chartOptions.label.type
        ? chartOptions.label.type
        : chartOptions.labelType
        ? chartOptions.labelType
        : 'middle'

      return chartOptions
    },
  },
  tooltipSetting: {
    settingToChartOption: (
      setting: IKeyValue,
      chartType?: string | string[]
    ) => {
      const {
        tooltipIsPercent,
        tooltipPrecision,
        labelKey,
        tooltipIsShow,
        heatMapDataKey,
      } = setting
      // eslint-disable-next-line @typescript-eslint/no-use-before-define
      if (
        !tooltipIsShow ||
        (chartType &&
          disableTooltipFormatterChart.has(parseChartType(chartType)))
      ) {
        delete setting.tooltip
        return setting
      }
      let { valueKey, yAxisAttribute } = setting
      const percentFlag = tooltipIsPercent
      const precisionFlag =
        typeof tooltipPrecision === 'number' &&
        tooltipPrecision >= 0 &&
        tooltipPrecision <= 9 // 小数位数 0-9之间

      // AreaRangeChart和BoxLineChart需要特殊处理
      const rangeFlag =
        setting.realChartType === 'AreaRangeChart' ||
        setting.realChartType === 'BoxLineChart'

      if (rangeFlag) {
        setting.tooltip = {
          customItems: (data: any) => {
            data.forEach((d: any) => {
              if (
                d?.data?.type === undefined &&
                setting.secondColor !== undefined &&
                setting.secondColor !== null
              ) {
                // 因为组件库中未返回颜色值，暂时在本地进行计算
                d.color =
                  setting.secondColor.startsWith('#') &&
                  setting.secondColor.length === 7
                    ? `${setting.secondColor}7f`
                    : setting.secondColor
              }

              // 处理格式
              let values = d.data.value
              if (!Array.isArray(values)) {
                values = [values] // 全部构造成数组格式
              }
              if (!values.some((v: any) => typeof v !== 'number')) {
                values = values.map((v: any) => {
                  let value: any = new Big(v)
                  if (percentFlag) {
                    value = value.times(100)
                  }
                  if (precisionFlag) {
                    value = value.toFixed(tooltipPrecision)
                  } else {
                    value = value.toNumber()
                  }
                  return percentFlag ? `${value}%` : value
                })
              }
              d.value = values.join('-')
            })

            return data
          },
        }
      } else {
        setting.tooltip = {
          formatter: (data: any) => {
            // 是否进入formatter处理
            if (
              Array.isArray(setting.valueKey) &&
              setting.valueKey.length === 2
            ) {
              // 柱线混合的特殊处理，直接提前返回，此处只考虑度量两个的情况，因为2个与3个度量的data结构不同
              ;[valueKey] = setting.valueKey.filter((key) =>
                Object.keys(data).includes(key)
              )
              yAxisAttribute = valueKey
              let value: any = data[valueKey]
              value = new Big(value)
              if (percentFlag) {
                value = value.times(100)
              }
              if (precisionFlag) {
                value = value.toFixed(tooltipPrecision) // string
              } else {
                value = value.toNumber()
              }
              return {
                name: yAxisAttribute,
                value: percentFlag ? `${value}%` : value,
              }
            }
            // 考虑度量为三个及以上的情况
            if (
              Array.isArray(setting.valueKey) &&
              setting.valueKey.length > 2
            ) {
              yAxisAttribute = setting.valueKey
            }
            // seriesField 是推荐chart过来的在堆叠、分组下的字段
            if (setting.seriesField) {
              return {
                name: data[setting.seriesField],
                value: data[valueKey],
              }
            }
            const flag =
              (heatMapDataKey && typeof data[heatMapDataKey] === 'number') ||
              (Array.isArray(yAxisAttribute) && yAxisAttribute.length > 1
                ? typeof data.value === 'number' ||
                  typeof data.value_left === 'number' ||
                  typeof data.value_right === 'number'
                : typeof data[valueKey] === 'number')
            if (flag) {
              let value: any = data[heatMapDataKey] || data[valueKey]
              let label: string =
                data.diffField || heatMapDataKey || data[labelKey]
              if (Array.isArray(yAxisAttribute) && yAxisAttribute.length >= 2) {
                // yAxisAttribute的情况下 >=2,如多条linechart，返回的data 固定格式为 { label: 'xxx', value: yyy, type: 'ccc'}
                // 柱线混合图多yAxisAttribute>=3，返回的data 固定格式为 { label: 'xxx', value_left或value_right: yyy, type: 'ccc'}
                if (data.value_left !== undefined) {
                  value = data.value_left
                } else if (data.value_right !== undefined) {
                  value = data.value_right
                } else {
                  value = data.value
                }
                label = data.type
              }
              value = new Big(value)
              if (percentFlag) {
                value = value.times(100)
              }
              if (precisionFlag) {
                value = value.toFixed(tooltipPrecision) // string
              } else {
                value = value.toNumber()
              }
              return {
                name: label,
                value: percentFlag ? `${value}%` : value,
              }
            }
            return {
              name: heatMapDataKey || data[labelKey],
              value: heatMapDataKey ? data[heatMapDataKey] : data[valueKey],
            }
          },
        }
      }

      return setting
    },
  },
  quadrantLabel: {
    settingToChartOption: (setting: IKeyValue) => {
      ;[
        'quadrantLabelTR',
        'quadrantLabelTL',
        'quadrantLabelBL',
        'quadrantLabelBR',
      ].forEach((key) => {
        // eslint-disable-next-line unicorn/prevent-abbreviations
        let positionStr = setting[`${key}PositionStr`]?.trim()
        if (positionStr) {
          positionStr = positionStr.replace('，', ',').replace(/\s+/, '')
          setting[`${key}Position`] = positionStr.split(',')
        }
      })
      return setting
    },
  },
}

/**
 * 解析不同chart类型下，proto config的信息
 * 如：满足某些情况下需要隐藏一些配置
 */
const parseProtoConfigFunc: IKeyValue = {
  // chartType: (protoConfig: 用于渲染成form的配置信息, formData: 渲染成form的value) => {}
}

/**
 * 解析topN相关的配置，需重新获取数据
 * @param setting 配置
 */
// function parseTopNSettiong(setting: KeyValue) {

// }

/**
 * 把form配置的属性转换成可渲染的组件配置
 * 防止1属性控制多个组件配置的情况
 * @param setting 组件的属性配置
 * @returns 可以render的chartOption
 */
export function parseSettingToChartOption(setting: IKeyValue) {
  Object.keys(parseSettingFunction).forEach((key) => {
    if (typeof parseSettingFunction[key].settingToChartOption === 'function') {
      setting = parseSettingFunction[key].settingToChartOption(setting)
    }
  })
  return setting
}

/**
 * 把组件配置转换成form配置的属性值
 * 防止多个组件配置对应一个form属性的情况
 * @param setting 组件的属性配置
 * @returns 可以render的chartOption
 */
export function parseChartOptionToFormSettiong(chartOptions: IKeyValue) {
  Object.keys(parseSettingFunction).forEach((key) => {
    if (typeof parseSettingFunction[key].chartOptionToSetting === 'function') {
      chartOptions =
        parseSettingFunction[key].chartOptionToSetting(chartOptions)
    }
  })
  return chartOptions
}

/**
 * 获取可视化数据
 */
export async function queryWidgetData(parameters: IKeyValue) {
  const response = await getWidgetData({
    data: parameters,
  })

  if (response.data.code === 100) {
    return response.data.result
  }
  return []
}

/**
 * 转换数据
 */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function parseGraphWidgetData({
  nodes = [],
  links = [],
}: {
  nodes: IKeyValue[]
  links: IKeyValue[]
}) {
  return {
    nodes,
    edges: links,
  }
}

/**
 * 获取graph widget 数据
 */
export async function queryGraphWidgetData(
  parameters: IKeyValue,
  filterCallback?: Function
) {
  const response = await loadGraphData({
    data: parameters,
  })

  if (response.data.code === 100) {
    const data = filterCallback
      ? filterCallback(response.data.result)
      : response.data.result
    return parseGraphWidgetData(data)
  }
  return { nodes: [], edges: [] }
}

/**
 * 校验fetchForm中的表单值是否合规，如 topN不能为空等
 * @param fieldValues 表单值
 */
export function checkFieldsValue(fieldValues: IKeyValue): boolean {
  if (!fieldValues || fieldValues.topN === undefined) {
    // topN不能为空
    return false
  }
  return true
}

/**
 * 解析fetchform 组成的查询参数
 */
export function parseFetchFormFields(
  fieldValues: IKeyValue,
  rawWidgetJson: IKeyValue
) {
  Object.keys(fieldValues).forEach((key) => {
    if (key === 'topN') {
      const topN = Number.parseInt(fieldValues[key], 10)
      rawWidgetJson.config.topN = topN
      rawWidgetJson.config.values = rawWidgetJson.config.values.map(
        (item: IKeyValue) => ({ ...item, topN })
      )
    }
  })

  return rawWidgetJson
}

/**
 * 解析 getData 接口查询回来的表格数据
 * @param dataResult
 * @returns
 */
export function parseGetDataResult(
  dataResult: { columns: IKeyValue[]; data: any[]; extraData?: any },
  chartType?: string,
  chartData?: IKeyValue
) {
  const data = cloneDeep(dataResult)
  const newResult: IKeyValue[] = []
  dataResult.data.forEach((dataItem: any) => {
    const item: IKeyValue = {}
    data.columns.forEach((column: IKeyValue, index: number) => {
      item[column.name] = dataItem[index]
    })
    newResult.push(item)
  })

  if (chartType === 'geographicMap') {
    // 地图组件数据需要额外处理
    return (
      dealMapData(chartData, newResult, data.extraData?.coordinates) ||
      newResult
    )
  }

  // if (['donutChart', 'pieChart'].includes(chartType as string)) {
  //   return dealPieChartData(chartData as KeyValueStore, result || [])
  // }
  return newResult
}

/**
 * 将 getData 接口查询回来的表格数据 按label和group重新排序并转为string格式
 */
export function restructGetDataResult(
  data: IKeyValue[],
  widgetJson: IWidgetJson
) {
  if (data.length > 0) {
    let dataResult = cloneDeep(data)
    const keyColumns: Array<string> = widgetJson.config.keys
      .filter((column: any) => {
        return typeof dataResult[0][column.col] === 'number'
      })
      .map((column: any) => column.col)
    /*
    if (keyColumns.length > 0) {
      // 重新排序
      dataResult.sort((a: IKeyValue, b: IKeyValue) => {
        const keyColumn = keyColumns.find((k: string) => {
          return a[k] - b[k] !== 0
        })
        return keyColumn ? a[keyColumn] - b[keyColumn] : 0
      })
    }
    */

    // 按label和groups转为string格式
    if (widgetJson.config.groups) {
      widgetJson.config.groups.forEach((column: any) => {
        if (typeof dataResult[0][column.col] === 'number') {
          keyColumns.push(column.col)
        }
      })
    }
    if (keyColumns.length > 0) {
      dataResult = dataResult.map((item: IKeyValue) => {
        const newItem: IKeyValue = {}
        keyColumns.forEach((keyColumn) => {
          newItem[keyColumn] = item[keyColumn].toString()
        })
        return {
          ...item,
          ...newItem,
        }
      })
    }

    return dataResult
  }
  return data
}

/**
 * 解析/禁用 chart 的某些配置描述(用于渲染form)等
 * @param chartType chart类型
 * @param protoConfig chart proto config 描述
 * @param formData chart form value值
 */
export function parseChartProtoConfig(
  chartType: string,
  protoConfig: IKeyValue,
  formData?: IKeyValue
) {
  if (parseProtoConfigFunc[chartType]) {
    protoConfig = parseProtoConfigFunc[chartType](protoConfig, formData)
  }

  return protoConfig
}

/**
 * 从form表单的值转换成widgetJson 数据
 */
export function convertFormDataToWidgetJson(
  formData: any,
  chartType: string,
  columns: IColumn[]
) {
  // eslint-disable-next-line unicorn/prevent-abbreviations
  const {
    isAggr,
    topN,
    labelKeyObj: labelKeyObject = {},
    yLabelKeyObj: yLabelKeyObject,
    valueKeyObjList: valueKeyObjectList = [],
    groupBy,
  } = formData
  const widgetJson: IWidgetJson = {
    isAggr,
    config: {
      topN,
      filters: [],
      keys: [
        {
          col: labelKeyObject.value,
          values: '',
          filterType: '',
          sort: labelKeyObject.sort,
          desc: labelKeyObject.desc,
        },
      ],
      values: (valueKeyObjectList || []).map(
        (data: { value: string; func: string; sort: '' | 'asc' | 'desc' }) => {
          if (chartType === 'scatterplot') {
            // 散点图度量可选择非数值类型，但是聚合函数只能为count（默认不传就是count）
            const value = {
              col: data.value,
              sort: data.sort,
              aggregate_type: data.func,
              topN,
            }
            const targetColumn = columns.filter(
              (column) => column.name === data.value
            )[0]
            if (
              targetColumn &&
              !['decimal', 'int'].includes(targetColumn.desc) &&
              value.aggregate_type !== 'count'
            ) {
              // @ts-ignore
              delete value.aggregate_type
            }
            return value
          }
          return {
            col: data.value,
            sort: data.sort,
            aggregate_type: data.func,
            topN,
          }
        }
      ),
    },
  }
  if (yLabelKeyObject) {
    widgetJson.config.keys.push({
      col: yLabelKeyObject.value,
      values: '',
      filterType: '',
      sort: yLabelKeyObject.sort,
    })
  }
  if (groupBy) {
    widgetJson.config.groups = [
      {
        col: groupBy,
        values: [],
      },
    ]
  }
  return widgetJson
}

/**
 * for graph-linechart demo
 * 将graph数据和普通chart的配置组合到一起
 * @param graphData
 * @param chartOptions 普通chart的配置
 * @param combineField 关联字段
 */
export function combineGraphLineChartData(
  graphData: { nodes: IKeyValue[] },
  chartOptions: IKeyValue,
  combineField: string
) {
  if (!combineField || !chartOptions.value || chartOptions.value.length === 0) {
    return graphData
  }

  ;(graphData.nodes || []).forEach((node) => {
    // eslint-disable-next-line unicorn/prevent-abbreviations
    const parsedAttrs = node.attrs.reduce((accu: any, current: any) => {
      accu[current.key] = current.value
      return accu
    }, {})
    if (parsedAttrs.filterKey === combineField) {
      node.subChartOptions = {
        ...chartOptions,
        value: chartOptions.value.filter(
          (list: IKeyValue) => parsedAttrs[combineField] === list[combineField]
        ),
      }
    } else {
      node.subChartOptions = {
        ...chartOptions,
        value: [],
      }
    }
  })

  return graphData
}
//  增删类 ‘remove-scroll’
function handleClassChange(type: string, element: any) {
  element.forEach((item: any) => {
    if (type === 'remove') {
      item.classList.add('remove-scroll')
    } else {
      item.classList.remove('remove-scroll')
    }
  })
}
//  系统构建中可能有scroll bar 的元素类名列表
const compWithScrollList = [
  '.editor-box', //  table
  '.comp-filter-form', //  filter
  '.operator-configuration', //  operator
  '.el-table__body-wrapper', //  table
]

/**
 * 处理文本，表格中的scroll bar - 显示 or 隐藏
 * @param type
 * @returns
 */
export function handleScrollBar(type: string) {
  compWithScrollList.forEach((item: string) => {
    const element = document.querySelectorAll(item)
    if (element.length > 0) {
      handleClassChange(type, element)
    }
  })
  //  fix for cut off print page
  const splitBlank = document.querySelectorAll('.blank')
  if (splitBlank.length > 0) {
    splitBlank.forEach((item: any) => {
      if (type === 'remove') {
        item.style.height = '55px'
      } else {
        item.style.height = '54px'
      }
    })
  }
}

/**
 * 获取graph数据，包括dagre、graph-lineChart、拼接节点位置
 * @param gridItem
 * @param projectId
 * @returns
 */
export async function getWidgetGraphData(
  gridItem: GridItemDataInterface,
  projectId: string,
  filtercallback?: Function,
  publishNo?: string
) {
  const payload: any = {
    fileName: gridItem.chartOptions.dataId,
    projectId,
  }
  if (publishNo && publishNo.length > 0) {
    payload.publishNo = publishNo
  }
  const value = await queryGraphWidgetData(payload, filtercallback)

  // graph-line-chart demo start ************
  const {
    subDataId,
    combineField,
    labelKeyObj,
    valueKeyObjList,
    widgetInfo,
    subChartOptions,
  } = gridItem.chartOptions

  if (widgetInfo && publishNo && publishNo.length > 0) {
    widgetInfo.publishNo = publishNo
  }
  if (
    subDataId &&
    combineField &&
    labelKeyObj?.value &&
    valueKeyObjList.length > 0
  ) {
    const response = await getWidgetData({
      data: widgetInfo,
    })
    const subValue: {
      columns: IKeyValue[]
      data: any[]
      page?: { curPage: number; pageSize: number; totalElements: number }
    } = response.data.result
    let dataResult = parseGetDataResult(subValue)
    dataResult = restructGetDataResult(dataResult, widgetInfo.widgetJson)
    subChartOptions.value = dataResult
    combineGraphLineChartData(value, subChartOptions, combineField)
  }
  // graph-line-chart demo end ************

  return value
}

/* 像tooltip、label等需要formatter时是通过formatter函数来进行，这种函数无法记录到chartOptions中
 * 只能通过配置转换成 formatter函数
 * @param chartOptions chart 配置
 */
export function parseChartOptionToFunction(
  chartOptions: IKeyValue,
  chartType?: string | string[]
) {
  parseSettingFunction.tooltipSetting.settingToChartOption(
    chartOptions,
    chartType
  )
  parseSettingFunction.labelSetting.settingToChartOption(chartOptions)
}
